﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using LingDong.ConfigProvider;
using NLog;
using LingDong.HtmlParser;

namespace LingDong.DataProvider
{
    /// <summary>
    /// This is a data reader for normal html
    /// Input path should be a directory contains many files, each file is a html page
    /// The program will traversal the directory recursionly and returns all files
    /// </summary>
    public class NormalHTMLReader : IDataReader
    {
        #region Contructors

        public NormalHTMLReader()
        {
            logger = LogManager.GetCurrentClassLogger();

            string path = ConfigDataProvider.Default.NormalHTMLReaderPath;
            if (!Directory.Exists(path))
            {
                throw new ArgumentException("path");
            }

            fileNameList = Directory.GetFiles(path, "*", SearchOption.AllDirectories).ToList();
            currentDataFileIndex = fileNameList.Count;
        }

        #endregion
        

        #region Public Members

        /// <summary>
        /// Get next text data from people daily corpus
        /// </summary>
        /// <returns></returns>
        public DataEntity GetNextData()
        {
            if (IsAllDataRead())
                return null;

            string curFile = fileNameList[--currentDataFileIndex];

            DataEntity data = new DataEntity();
            data.Url = curFile;
            data.Content = ReadFileWithEncoding(curFile, Encoding.Default);
            Encoding declaredEncode = HtmlContent.GetDeclaredEncoding(data.Content);
            if (declaredEncode != Encoding.Default)
            {
                data.Content = ReadFileWithEncoding(curFile, declaredEncode);
            }
            return data;
        }

        /// <summary>
        /// Return if all data in data file has been read
        /// </summary>
        /// <returns></returns>
        public bool IsAllDataRead()
        {
            return currentDataFileIndex <= 0;
        }

        /// <summary>
        /// PeopleDaily corpus contains only text
        /// </summary>
        /// <returns></returns>
        public bool IsDataContainsOnlyText()
        {
            return false;
        }

        #endregion


        #region Private Methods

        private string ReadFileWithEncoding(string curFile, Encoding encoding)
        {
            string content;
            using (StreamReader sr = new StreamReader(curFile, encoding))
            {
                content = sr.ReadToEnd();
            }
            return content;
        }

        #endregion


        #region Private Members

        private Logger logger;

        private int currentDataFileIndex;
        private List<string> fileNameList;

        #endregion


        #region Disposable related

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposed)
            {
                return;
            }

            disposed = true;
        }

        private bool disposed = false;

        #endregion
    }
}
